package cn.school.publicPhone.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.school.common.api.CommonPage;
import cn.school.common.api.CommonResult;
import cn.school.common.utils.StringUtils;
import cn.school.common.utils.SysUserUtils;
import cn.school.publicPhone.dao.StudentCallQuotaDao;
import cn.school.publicPhone.dao.StudentCallRecordsDao;
import cn.school.publicPhone.dao.StudentQuotaRecordsDao;
import cn.school.publicPhone.service.StudentCallService;
import cn.school.publicPhone.vo.StudentCallQuota;
import cn.school.publicPhone.vo.StudentCallQuotaRecords;
import cn.school.publicPhone.vo.StudentCallRecords;
import cn.school.publicPhone.vo.StudentCallRecordsVo;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.SyncReadListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @className: StudentCallServiceImpl
 * @author: Alex
 * @date: 2023/6/25
 **/
@Service
@Slf4j
public class StudentCallServiceImpl extends ServiceImpl<StudentCallQuotaDao, StudentCallQuota> implements StudentCallService {

	@Resource
	private StudentCallRecordsDao studentCallRecordsDao;

	@Resource
	private StudentQuotaRecordsDao studentQuotaRecordsDao;

	@Override
	@Transactional
	public int saveStudentCallRecords(StudentCallRecords studentCallRecords) {
		// 获取剩余通话时长
		String studentRemainingDuration = getStudentRemainingDuration(studentCallRecords.getStudentId());
		// 更新剩余通话时长
		int remainingDuration = Integer.parseInt(studentRemainingDuration) - Integer.parseInt(studentCallRecords.getCallDuration());

		studentCallRecords.setRemainingDuration(String.valueOf(remainingDuration));
		LambdaUpdateWrapper<StudentCallQuota> updateWrapper = new LambdaUpdateWrapper<>();
		updateWrapper.eq(StudentCallQuota::getStudentId, studentCallRecords.getStudentId())
				.set(StudentCallQuota::getRemainingDuration, String.valueOf(remainingDuration))
				.set(StudentCallQuota::getModifyBy, SysUserUtils.getSysUser().getUsername())
				.set(StudentCallQuota::getModifyTime, new Date());
		boolean update = update(updateWrapper);
		if (!update) {
			log.error("更新通话额度失败！");
		}
		// 将通话记录保存
		return studentCallRecordsDao.insert(studentCallRecords);
	}

	@Override
	public String getStudentRemainingDuration(String studentId) {
		LambdaQueryWrapper<StudentCallQuota> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(StudentCallQuota::getStudentId, studentId);
		StudentCallQuota studentCallQuota = getOne(wrapper);
		return studentCallQuota.getRemainingDuration();
	}

	@Override
	public String getRemainingDuration(String studentId) {
		LambdaQueryWrapper<StudentCallRecords> lambdaQueryWrapper = new LambdaQueryWrapper<>();
		lambdaQueryWrapper.eq(StudentCallRecords::getStudentId, studentId)
				.inSql(StudentCallRecords::getId, "select max(id) from t_student_call_records where student_id = '" + studentId + "'");
		StudentCallRecords studentCallRecords = studentCallRecordsDao.selectOne(lambdaQueryWrapper);
		return studentCallRecords.getRemainingDuration();
	}

	@Override
	@Transactional
	public Boolean setCallQuota(List<StudentCallQuota> callQuotas) {
		if (CollectionUtil.isEmpty(callQuotas)) {
			return false;
		}

		for (StudentCallQuota callQuota : callQuotas) {
			if (Objects.nonNull(callQuota.getId())) {
				callQuota.setStudentCallQuota(String.valueOf(Integer.parseInt(callQuota.getQuotaSecond()) + Integer.parseInt(callQuota.getStudentCallQuotaSecond())));
				callQuota.setRemainingDuration(String.valueOf(Integer.parseInt(callQuota.getQuotaSecond()) + Integer.parseInt(callQuota.getRemainingDurationSecond())));
				callQuota.setModifyBy(SysUserUtils.getSysUser().getUsername());
				callQuota.setModifyTime(new Date());
				continue;
			}
			callQuota.setCreateBy(SysUserUtils.getSysUser().getUsername());
			callQuota.setCreateTime(new Date());
			callQuota.setRemainingDuration(callQuota.getStudentCallQuota());
		}
		insertCallQuotaRecords(callQuotas);
		return saveOrUpdateBatch(callQuotas);
	}

	private void insertCallQuotaRecords(List<StudentCallQuota> callQuotas) {
		for (StudentCallQuota callQuota : callQuotas) {
			StudentCallQuotaRecords record = new StudentCallQuotaRecords();
			record.setStudentId(callQuota.getStudentId());
			record.setStudentName(callQuota.getStudentName());
			record.setRechargeType(0);
			String rechargeTime = "";
			if (Objects.isNull(callQuota.getId())) {
				rechargeTime = callQuota.getStudentCallQuota();
			} else {
				rechargeTime = callQuota.getQuotaSecond();
			}
			if (Integer.parseInt(rechargeTime) > 0) {
				record.setRechargeType(1);
			}
			record.setRechargeTime(rechargeTime);
			record.setCreateBy(SysUserUtils.getSysUser().getUsername());
			record.setCreateTime(DateUtil.date());
			studentQuotaRecordsDao.insert(record);
		}
	}

	private String convertSecondFormat(String callQuota) {
		String[] hours = callQuota.split("小时");
		String hour = hours[0];
		String minute = hours[1].split("分钟")[0];
		String second = hours[1].split("分钟")[1].replace("秒", "");

		return Integer.parseInt(hour) * 3600 + Integer.parseInt(minute) * 60 + second + "";
	}

	@Override
	public CommonPage<StudentCallRecords> getRecordsList(StudentCallRecordsVo vo) {
		LambdaQueryWrapper<StudentCallRecords> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(StringUtils.isNotEmpty(vo.getStudentId()), StudentCallRecords::getStudentId, vo.getStudentId());
		wrapper.eq(StringUtils.isNotEmpty(vo.getStudentName()), StudentCallRecords::getStudentName, vo.getStudentName());
		Page<StudentCallRecords> recordsPage = studentCallRecordsDao.selectPage(new Page<>(vo.getPageNum(), vo.getPageSize()), wrapper);
		return CommonPage.restPage(recordsPage);
	}

	@Override
	public CommonPage<StudentCallQuota> getCallQuotaList(StudentCallRecordsVo vo) {
		LambdaQueryWrapper<StudentCallQuota> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(StringUtils.isNotEmpty(vo.getStudentId()), StudentCallQuota::getStudentId, vo.getStudentId());
		wrapper.eq(StringUtils.isNotEmpty(vo.getStudentName()), StudentCallQuota::getStudentName, vo.getStudentName());
		Page<StudentCallQuota> page = page(new Page<>(vo.getPageNum(), vo.getPageSize()), wrapper);
		if (CollectionUtil.isNotEmpty(page.getRecords())) {
			for (StudentCallQuota record : page.getRecords()) {
				record.setQuotaSecond(record.getRemainingDuration());
				record.setStudentCallQuotaSecond(record.getStudentCallQuota());
				record.setStudentCallQuota(convertQuotaFormat(record.getStudentCallQuota()));
				record.setRemainingDurationSecond(record.getRemainingDuration());
				record.setRemainingDuration(convertQuotaFormat(record.getRemainingDuration()));
			}
		}
		return CommonPage.restPage(page);
	}

	@Override
	public Boolean deleteQuotaByIds(List<Long> list) {
		return removeByIds(list);
	}

	@Override
	public CommonResult<String> importContactsList(InputStream inputStream) {
		// 数据转换
		List<StudentCallQuota> readList = new ArrayList<>();
		readList = EasyExcel.read(inputStream)
				.registerReadListener(new SyncReadListener())
				.head(StudentCallQuota.class)
				.sheet(0)
				.headRowNumber(1)
				.doReadSync();
		for(StudentCallQuota sq:readList){
			for (int i = 0; i < sq.getStudentCallQuota().length(); i++) {
				System.out.println(sq.getStudentCallQuota().charAt(i));
				if (!Character.isDigit(sq.getStudentCallQuota().charAt(i))) {
					return CommonResult.failed("导入失败,学生通话额度(秒)必须是纯数字");
				}
			}
		}
//		EasyExcel.read(inputStream, StudentCallQuota.class, new SyncReadListener() {
//
//			@Override
//			public void invoke(Object object, AnalysisContext context) {
//				//读取到的数据被存入bean
//				StudentCallQuota studentInfo = (StudentCallQuota) object;
//				readList.add(studentInfo);
//			}
//		}).doReadAll();
		List<String> collect = readList.stream().map(StudentCallQuota::getStudentId).collect(Collectors.toList());
		// 数据校验
		// 先获取数据库中存在的数据 studentId查询
		LambdaQueryWrapper<StudentCallQuota> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(StudentCallQuota::getStudentId, collect);
		List<StudentCallQuota> callQuotas = baseMapper.selectList(queryWrapper);
		// 数据库中不存在当前导入数据
/*		if (CollectionUtil.isEmpty(callQuotas)) {
			for (StudentCallQuota callQuota : readList) {
				callQuota.setCreateBy(SysUserUtils.getSysUser().getUsername());
				callQuota.setCreateTime(new Date());
				callQuota.setRemainingDuration(callQuota.getStudentCallQuota());
			}
			boolean b = saveOrUpdateBatch(readList);
			if (b) {
				return CommonResult.success("导入成功");
			}
			return CommonResult.failed("导入失败");
		}*/

		readList.forEach(callQuota -> {
					callQuotas.stream()
							.filter(studentCallQuota -> Objects.equals(callQuota.getStudentId(), studentCallQuota.getStudentId()))
							.findFirst()
							.ifPresent(studentCallQuota -> {
								callQuota.setId(studentCallQuota.getId());
								callQuota.setModifyTime(new Date());
								callQuota.setModifyBy(SysUserUtils.getSysUser().getUsername());
								callQuota.setRemainingDuration(callQuota.getStudentCallQuota());
							});
					if (Objects.isNull(callQuota.getCreateBy())) {
						callQuota.setCreateTime(new Date());
						callQuota.setCreateBy(SysUserUtils.getSysUser().getUsername());
						callQuota.setRemainingDuration(callQuota.getStudentCallQuota());
					}
				}

		);

		// 更新或者保存数据
		boolean b = saveOrUpdateBatch(readList);
		if (b) {
			return CommonResult.success("导入成功");
		}
		return CommonResult.failed("导入失败");
	}

	/**
	 * 将秒数转换为 时分秒格式
	 *
	 * @return
	 * @author alex
	 * @param: callQuota
	 * @date 2023/6/27 16:57
	 */
	private String convertQuotaFormat(String callQuota) {
		int hour = Integer.parseInt(callQuota) / 60 / 60;
		int minute = Integer.parseInt(callQuota) / 60 % 60;
		int second = Integer.parseInt(callQuota) % 60;

		return hour + "小时" + minute + "分钟" + second + "秒";
	}
}
